#include "Graphics/PiccoloVKFrameBuffer.h"

#include <Graphics/PiccoloVKDevice.h>
#include <Graphics/PiccoloVKImage.h>
#include <Graphics/PiccoloVKImageView.h>
#include <Graphics/PiccoloVKRenderPass.h>

namespace Piccolo
{
    PiccoloVKFrameBuffer::PiccoloVKFrameBuffer(PiccoloVKDevice *device, PiccoloVKRenderPass *renderPass, const std::vector<std::shared_ptr<PiccoloVKImage>>& images, uint32_t width, uint32_t height)
        : mDevice(device), mRenderPass(renderPass), mWidth(width), mHeight(height), mImages(images)
    {
        RecreateFrameBuffer(images, width, height);
    }

    PiccoloVKFrameBuffer::~PiccoloVKFrameBuffer()
    {
        VK_D(Framebuffer, mDevice->GetLogicDevice(), mFramebuffer);
    }

    bool PiccoloVKFrameBuffer::RecreateFrameBuffer(const std::vector<std::shared_ptr<PiccoloVKImage>>& images, uint32_t width, uint32_t height)
    {
        VK_D(Framebuffer, mDevice->GetLogicDevice(), mFramebuffer);

        mWidth = width;
        mHeight = height;
        mImageViews.clear();

        VkImageView attachments[images.size()];
        for (int i = 0; i < images.size(); ++i)
        {
            bool isDepthFormat = IsDepthOnlyFormat(images[i]->GetFormat());
            mImageViews.push_back(std::make_shared<PiccoloVKImageView>(mDevice, images[i]->GetImage(), images[i]->GetFormat(),
                isDepthFormat ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT));
            attachments[i] = mImageViews[i]->GetImageView();
        }

        VkFramebufferCreateInfo framebufferInfo =
        {
            .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
            .pNext = nullptr,
            .flags = 0,
            .renderPass = mRenderPass->GetRenderPass(),
            .attachmentCount = static_cast<uint32_t>(mImageViews.size()),
            .pAttachments = attachments,
            .width = width,
            .height = height,
            .layers = 1
        };
        VkResult ret = vkCreateFramebuffer(mDevice->GetLogicDevice(), &framebufferInfo, nullptr, &mFramebuffer);
        LOG_T("Framebuffer {0}, new: {1}, width: {2}, height: {3}, view count: {4}", __FUNCTION__, (void*)mFramebuffer, mWidth, mHeight, mImageViews.size());
        return ret == VK_SUCCESS;
    }
}
